/*! \file
 * \brief Enter a brief description here.
 *
 * Enter a detailed description here. (optional)
 * \author Author (Ivo Wingelaar)
 * \date Date (2011)
 * \version Version (0.0.1)
 * \copyright Copyright (GNU LGPL v3)
 */

#ifndef __LYNX_SHADER_MATERIAL_RENDERER_HPP_INCLUDED__
#define __LYNX_SHADER_MATERIAL_RENDERER_HPP_INCLUDED__

#include "LynxConfig.hpp"
#define GL_GLEXT_LEGACY 1

#ifdef _LYNX_WINDOWS_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <GL/gl.h>
#endif // _LYNX_WINDOWS_
#ifdef _LYNX_LINUX_
#include <GL/gl.h>
#endif // _LYNX_LINUX_

#include "LynxMaterialRenderer.hpp"
#include "LynxGPUProgrammingServices.hpp"

namespace Lynx
{

class VideoManager_C;
class MaterialRenderer;

//! Class for using vertex and pixel shaders with OpenGL
class ShaderMaterialRenderer : public MaterialRenderer
{
public:
    //! Constructor
    ShaderMaterialRenderer(VideoManager_C* driver, int32_t& outMaterialTypeNr, const char* vertexShaderProgram, const char* pixelShaderProgram, ShaderConstantSetCallBack* callback, MaterialRenderer* baseMaterial, int32_t userData);

    //! Destructor
    virtual ~ShaderMaterialRenderer();

    virtual void on_set_material(const Material& material, const Material& lastMaterial, bool resetAllRenderstates, MaterialRendererServices* services);

    virtual bool on_render(MaterialRendererServices* service, E_VERTEX_TYPE vtxtype);

    virtual void on_unset_material();

    //! Returns if the material is transparent.
    virtual bool is_transparent() const;

protected:

    //! constructor only for use by derived classes who want to
    //! create a fall back material for example.
    ShaderMaterialRenderer(VideoManager_C* driver, ShaderConstantSetCallBack* callback, MaterialRenderer* baseMaterial, int32_t userData=0);

    // must not be called more than once!
    void init(int32_t& outMaterialTypeNr, const char* vertexShaderProgram, const char* pixelShaderProgram, E_VERTEX_TYPE type);

    bool createPixelShader(const char* pxsh);
    bool createVertexShader(const char* vtxsh);
    bool checkError(const char* type);

    VideoManager_C* mDriver;
    ShaderConstantSetCallBack* mCallBack;
    MaterialRenderer* mBaseMaterial;

    GLuint mVertexShader;
    // We have 4 values here, [0] is the non-fog version, the other three are
    // ARB_fog_linear, ARB_fog_exp, and ARB_fog_exp2 in that order
    std::vector<GLuint> mPixelShader;
    int32_t mUserData;
};

} // namespace Lynx

#endif // __LYNX_SHADER_MATERIAL_RENDERER_HPP_INCLUDED__

